#include "new_contact.h"
void menu( )
{
    printf("*******************************\n");
    printf("***** 1.add      2.del    *****\n");
    printf("***** 3.search   4.modify *****\n");
    printf("***** 5.sort     6.print  *****\n");
    printf("*********   0.Exit    *********\n");
    printf("*******************************\n");
}

static void check_capacity(contact* pc)//扩容函数
{
    if(pc->sz == pc->capacity)
    {
        Peoinfo* ptr= (Peoinfo*) realloc(pc->data,(pc->capacity+INC_SZ)*sizeof(Peoinfo));//扩容
        if(ptr!=NULL)
        {
            pc->data = ptr;
            pc->capacity += INC_SZ;
            printf("扩容成功！\n"); 
        }
        else
            perror("check_capacity");
    }
}

static void Loadcontact(contact* pc)//加载通讯录文件内容
{
    FILE* pf=fopen("contact.dat","r");
    if(pf == NULL)
    {
        perror("Loadcontact");
        return;
    }
    Peoinfo tmp = {0};
    while(fread(&tmp,sizeof(Peoinfo),1,pf))
    {
        check_capacity(pc);
        pc->data[pc->sz] = tmp;
        pc->sz++;
    }
    fclose(pf);
    pf=NULL;

}

void reset(contact* pc)//初始化函数
{
    Peoinfo* ptr= (Peoinfo*) malloc(DEF_SZ*sizeof(Peoinfo));
    if(ptr!=NULL)
    pc->data = ptr;
    else
    perror("reset");
    pc->sz = 0;
    pc->capacity = DEF_SZ;
    Loadcontact(pc);
}

void DestCon(contact* pc)//销毁函数
{
    free(pc->data);
    pc->data = NULL;
    pc->sz = 0;
    pc->capacity = 0;
}

int Addcontact(contact* pc)//添加函数
{
    check_capacity(pc);
    printf("请输入名字：\n");
    scanf("%s",pc->data[pc->sz].name);
    printf("请输入性别：\n");
    scanf("%s",pc->data[pc->sz].sex);
    printf("请输入年龄：\n");
    scanf("%d",&pc->data[pc->sz].age);//其他都是数组，数组名即地址，age为int类型，因此要&取地址
    printf("请输入电话：\n");
    scanf("%s",pc->data[pc->sz].tele);
    printf("请输入住址：\n");
    scanf("%s",pc->data[pc->sz].addr);
    pc->sz++;

    printf("添加成功！\n");
    return 0;
}

static int Findbyname(contact* pc,char name[])//删除函数内部比较函数
{
    for(int i=0;i<pc->sz;i++)
    {
        if(strcmp(pc->data[i].name,name)==0)
        return i;
    }
    return -1;
}

int Delcontact(contact* pc)//删除函数
{
    if(pc->sz==0)
    {
        printf("通讯录为空，无需删除！\n");
        return 0;
    }
    char name[20]={0};
    printf("请输入需要删除人的姓名：\n");
    scanf("%s",name);
    int pos= Findbyname(pc,name);
    if(pos==-1)
    {
    printf("要删除的人不存在！\n");
    return 0;
    }
    for(int i = pos ; i < pc->sz-1 ; i++)
    {
        pc->data[i]=pc->data[i+1];
    }
    memset(&(pc->data[pc->sz-1]),0,sizeof((pc->data[pc->sz-1])));//将最后一位置零(也可以不用这一步)
    if(pc->sz!=0)//保险判断（可以不用这一步）
    pc->sz--;
    printf("删除成功！\n");
    return 0;
}

int Searchcontact(contact* pc)//查找函数
{
    if(pc->sz==0)
    {
        printf("通讯录为空！\n");
        return 0;
    }
    char name[20]={0};
    printf("请输入需要查找人的姓名：\n");
    scanf("%s",name);
    int pos= Findbyname(pc,name);
    if(pos==-1)
    {
    printf("要查找的人不存在！\n");
    return 0;
    }
        printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n","姓名","性别","年龄","电话","住址");
        printf("%-20s\t%-5s\t%-5d\t%-12s\t%-20s\n",pc->data[pos].name,
                                                    pc->data[pos].sex,
                                                    pc->data[pos].age,
                                                    pc->data[pos].tele,
                                                    pc->data[pos].addr);
    return 0;
}

int Modifycontact(contact* pc)//修改函数
{
    char name[20]={0};
    printf("请输入需要修改人的姓名：\n");
    scanf("%s",name);
    int pos= Findbyname(pc,name);
    if(pos==-1)
    {
    printf("要修改的人不存在！\n");
    return 0;
    }
        printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n","姓名","性别","年龄","电话","住址");
        printf("%-20s\t%-5s\t%-5d\t%-12s\t%-20s\n",pc->data[pos].name,
                                                    pc->data[pos].sex,
                                                    pc->data[pos].age,
                                                    pc->data[pos].tele,
                                                    pc->data[pos].addr);
     printf("请修改名字：\n");
    scanf("%s",pc->data[pos].name);
    printf("请修改性别：\n");
    scanf("%s",pc->data[pos].sex);
    printf("请修改年龄：\n");
    scanf("%d",&pc->data[pos].age);//其他都是数组，数组名即地址，age为int类型，因此要&取地址
    printf("请修改电话：\n");
    scanf("%s",pc->data[pos].tele);
    printf("请修改住址：\n");
    scanf("%s",pc->data[pos].addr);

    printf("修改成功！\n");
    return 0;
}

static void swap(char* str1 , char* str2, int width)//一个字节一个字节地交换
{
    for(int i=0;i<width;i++)
    {
        char tmp = *str1;
        *str1 = *str2;
        *str2 = tmp;
        str1++;
        str2++;
    }
}

int sortby_age(const void*e1 , const void* e2)//以年龄排序
{
    return ((Peoinfo*)e1)->age - ((Peoinfo*) e2)->age;
}

int sortby_name(const void*e1 , const void* e2)//以名字排序
{
    return strcmp(((Peoinfo*)e1)->name,((Peoinfo*)e2)->name);
}

void Sortcontact
            (
                void* base,
                unsigned int size,
                unsigned int width,
                int (*cmp) (const void* e1,const void* e2)
            )//排序函数
{
    for(int i=0;i<size;i++)
    {
        int j=0;
        for(j=0;j<size-1-i;j++)
        {
            if( cmp( (char*)base+j*width , (char*)base+(j+1)*width )>0 )//以所传元素首地址为基础，元素类型所占字节为跨度
            {
                swap((char*)base+j*width , (char*)base+(j+1)*width , width);
            }
        }
    }
}


void Printcontact(contact* pc)//打印函数
{
    printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n","姓名","性别","年龄","电话","住址");
    for(int i=0;i<pc->sz;i++)
    {
        printf("%-20s\t%-5s\t%-5d\t%-12s\t%-20s\n",pc->data[i].name,
                                                    pc->data[i].sex,
                                                    pc->data[i].age,
                                                    pc->data[i].tele,
                                                    pc->data[i].addr);
    }
}

void Savecon(contact* pc)//保存内容到文件
{
    FILE* pf = fopen("contact.dat","w");//打开文件
    if(pf==NULL)
    {
        perror("Savecon");
        return;
    }

    for(int i=0;i<pc->sz;i++)//写入文件
    {
        fwrite(pc->data+i,sizeof(Peoinfo),1,pf);
    }

    fclose(pf);
    pf=NULL;
}